package com.xywh.wanandroid.ext


import android.annotation.SuppressLint
import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.Color
import android.net.Uri
import android.text.InputType
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import androidx.navigation.NavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.blankj.utilcode.util.ToastUtils
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.qmuiteam.qmui.skin.QMUISkinManager
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.xywh.wanandroid.MyApp
import com.xywh.wanandroid.R
import com.xywh.wanandroid.base.BaseConstant.Companion.SERVER_URL
import com.xywh.wanandroid.network.stateCallback.ListDataUiState
import com.xywh.wanandroid.util.CacheUtil
import com.xywh.wanandroid.util.SettingUtil
import com.xywh.wanandroid.weight.loadCallBack.EmptyCallback
import com.xywh.wanandroid.weight.loadCallBack.ErrorCallback
import com.xywh.wanandroid.weight.loadCallBack.LoadingCallback
import com.xywh.wanandroid.weight.recyclerview.DefineLoadMoreView
import com.yanzhenjie.recyclerview.SwipeRecyclerView
import me.hgj.jetpackmvvm.base.appContext
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.util.Random
import java.util.regex.Matcher
import java.util.regex.Pattern


/**
 * 设置view隐藏
 */
fun View.gone() {
    visibility = View.GONE
}

/**
 * 设置view显示
 */
fun View.visible() {
    visibility = View.VISIBLE
}


/**
 * 设置view占位隐藏
 */
fun View.invisible() {
    visibility = View.INVISIBLE
}

/**
 * 隐藏软键盘
 */
fun hideSoftKeyboard(activity: Activity?) {
    activity?.let { act ->
        val view = act.currentFocus
        view?.let {
            val inputMethodManager =
                act.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
            inputMethodManager.hideSoftInputFromWindow(
                view.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }
}

fun dp2px(dp: Int): Int {
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(),
        Resources.getSystem().getDisplayMetrics()
    ).toInt()
}

/**
 * 初始化普通的toolbar 只设置标题
 */
fun Toolbar.init(titleStr: String = "", toolbar_title: TextView): Toolbar {
//    setBackgroundColor(SettingUtil.getColor(appContext))
//    title = titleStr
    toolbar_title.text = titleStr
    return this
}

fun Toolbar.initMenuClose(
    titleStr: String = "",
    toolbar_title: TextView,
    resId: Int,
    onMenuItemClickListener: Toolbar.OnMenuItemClickListener,
    backImg: Int = R.drawable.icon_back_white,
    onBack: (toolbar: Toolbar) -> Unit
): Toolbar {
//    setBackgroundColor(SettingUtil.getColor(appContext))
//    title = titleStr.toHtml()
    toolbar_title.text = titleStr
    setNavigationIcon(backImg)
    setNavigationOnClickListener { onBack.invoke(this) }
    inflateMenu(resId)
    setOnMenuItemClickListener(onMenuItemClickListener)
    return this
}


fun Toolbar.initMenu(
    titleStr: String = "",
    toolbar_title: TextView,
    resId: Int,
    onMenuItemClickListener: Toolbar.OnMenuItemClickListener
): Toolbar {
//    setBackgroundColor(SettingUtil.getColor(appContext))
//    title = titleStr.toHtml()
    toolbar_title.text = titleStr
    inflateMenu(resId)
    setOnMenuItemClickListener(onMenuItemClickListener)
    return this
}


/**
 * 初始化有返回键的toolbar
 */
fun Toolbar.initClose(
    titleStr: String = "",
    toolbar_title: TextView,
    backImg: Int = R.drawable.icon_back_white,
    onBack: (toolbar: Toolbar) -> Unit,
): Toolbar {
//    setBackgroundColor(SettingUtil.getColor(appContext))
//    title = titleStr.toHtml()
    toolbar_title.text = titleStr
    setNavigationIcon(backImg)
    setNavigationOnClickListener { onBack.invoke(this) }
    return this
}


fun BottomNavigationViewEx.init(navigationItemSelectedAction: (Int) -> Unit): BottomNavigationViewEx {
    enableAnimation(true)
    setIconsMarginTop(40)
    enableShiftingMode(false)
    enableItemShiftingMode(true)
    itemIconTintList = SettingUtil.getColorStateList(SettingUtil.getColor(appContext))
    itemTextColor = SettingUtil.getColorStateList(appContext)
    setTextSize(12F)
    setOnNavigationItemSelectedListener {
        navigationItemSelectedAction.invoke(it.itemId)
        true
    }
    return this
}


/**
 * 拦截BottomNavigation长按事件 防止长按时出现Toast ---- 追求完美的大屌群友提的bug
 * @receiver BottomNavigationViewEx
 * @param ids IntArray
 */
fun BottomNavigationViewEx.interceptLongClick(vararg ids: Int) {
    val bottomNavigationMenuView: ViewGroup = (this.getChildAt(0) as ViewGroup)
    for (index in ids.indices) {
        bottomNavigationMenuView.getChildAt(index).findViewById<View>(ids[index])
            .setOnLongClickListener {
                true
            }
    }
}

/**
 * 设置加载中
 */
fun LoadService<*>.showLoading() {
    this.showCallback(LoadingCallback::class.java)
}

fun loadServiceInit(view: View, callback: () -> Unit): LoadService<Any> {
    val loadsir = LoadSir.getDefault().register(view) {
        //点击重试时触发的操作
        callback.invoke()
    }
    loadsir.showSuccess()
    SettingUtil.setLoadingColor(SettingUtil.getColor(appContext), loadsir)
    return loadsir
}

//绑定普通的Recyclerview
fun RecyclerView.init(
    layoutManger: RecyclerView.LayoutManager,
    bindAdapter: RecyclerView.Adapter<*>,
    isScroll: Boolean = true
): RecyclerView {
    layoutManager = layoutManger
    setHasFixedSize(true)
    adapter = bindAdapter
    isNestedScrollingEnabled = isScroll
    return this
}

//绑定SwipeRecyclerView
fun SwipeRecyclerView.init(
    layoutManger: RecyclerView.LayoutManager,
    bindAdapter: RecyclerView.Adapter<*>,
    isScroll: Boolean = true
): SwipeRecyclerView {
    layoutManager = layoutManger
    setHasFixedSize(true)
    adapter = bindAdapter
    isNestedScrollingEnabled = isScroll
    return this
}

fun SwipeRecyclerView.initFooter(loadmoreListener: SwipeRecyclerView.LoadMoreListener): DefineLoadMoreView {
    val footerView = DefineLoadMoreView(appContext)
    //给尾部设置颜色
    footerView.setLoadViewColor(SettingUtil.getOneColorStateList(appContext))
    //设置尾部点击回调
    footerView.setmLoadMoreListener(SwipeRecyclerView.LoadMoreListener {
        footerView.onLoading()
        loadmoreListener.onLoadMore()
    })
    this.run {
        //添加加载更多尾部
        addFooterView(footerView)
        setLoadMoreView(footerView)
        //设置加载更多回调
        setLoadMoreListener(loadmoreListener)
    }
    return footerView
}


fun RecyclerView.initFloatBtn(floatbtn: FloatingActionButton) {
    //监听recyclerview滑动到顶部的时候，需要把向上返回顶部的按钮隐藏
    addOnScrollListener(object : RecyclerView.OnScrollListener() {
        @SuppressLint("RestrictedApi")
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            if (!canScrollVertically(-1)) {
                floatbtn.visibility = View.INVISIBLE
            }
        }
    })
    floatbtn.backgroundTintList = SettingUtil.getOneColorStateList(appContext)
    floatbtn.setOnClickListener {
        val layoutManager = layoutManager as LinearLayoutManager
        //如果当前recyclerview 最后一个视图位置的索引大于等于40，则迅速返回顶部，否则带有滚动动画效果返回到顶部
        if (layoutManager.findLastVisibleItemPosition() >= 40) {
            scrollToPosition(0)//没有动画迅速返回到顶部(马上)
        } else {
            smoothScrollToPosition(0)//有滚动动画返回到顶部(有点慢)
        }
    }
}

//初始化 SwipeRefreshLayout
fun SwipeRefreshLayout.init(onRefreshListener: () -> Unit) {
    this.run {
        setOnRefreshListener {
            onRefreshListener.invoke()
        }
        //设置主题颜色
        setColorSchemeColors(SettingUtil.getColor(appContext))
    }
}

/**
 * 加载列表数据
 */
fun <T> loadListData(
    data: ListDataUiState<T>,
    baseQuickAdapter: BaseQuickAdapter<T, *>,
    loadService: LoadService<*>,
    recyclerView: SwipeRecyclerView,
    swipeRefreshLayout: SwipeRefreshLayout
) {
    swipeRefreshLayout.isRefreshing = false
    recyclerView.loadMoreFinish(data.isEmpty, data.hasMore)
    if (data.isSuccess) {
        //成功
        when {
            //第一页并没有数据 显示空布局界面
            data.isFirstEmpty -> {
                loadService.showEmpty()
            }
            //是第一页
            data.isRefresh -> {
                baseQuickAdapter.setList(data.listData)
                loadService.showSuccess()
            }
            //不是第一页
            else -> {
                baseQuickAdapter.addData(data.listData)
                loadService.showSuccess()
            }
        }
    } else {
        //失败
        if (data.isRefresh) {
            //如果是第一页，则显示错误界面，并提示错误信息
            loadService.showError(data.errMessage)
        } else {
            recyclerView.loadMoreError(0, data.errMessage)
        }
    }
}

/**
 * 设置错误布局
 * @param message 错误布局显示的提示内容
 */
fun LoadService<*>.showError(message: String = "") {
    this.setErrorText(message)
    this.showCallback(ErrorCallback::class.java)
}

fun LoadService<*>.setErrorText(message: String) {
    if (message.isNotEmpty()) {
        this.setCallBack(ErrorCallback::class.java) { _, view ->
            view.findViewById<TextView>(R.id.error_text).text = message
        }
    }
}

fun LoadService<*>.showEmpty(message: String = "") {
    this.setEmptyText(message)
    this.showCallback(EmptyCallback::class.java)
}

fun LoadService<*>.setEmptyText(message: String) {
    if (message.isNotEmpty()) {
        this.setCallBack(EmptyCallback::class.java) { _, view ->
            view.findViewById<TextView>(R.id.tv_empty_text).text = message
        }
    }
}

/**
 * 设置空布局
 */
fun LoadService<*>.showEmpty() {
    this.showCallback(EmptyCallback::class.java)
}


fun getClipboardContent(): String? {
    val cm: ClipboardManager =
        appContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    if (cm != null) {
        val data: ClipData? = cm.primaryClip
        if (data != null && data.itemCount > 0) {
            val item = data.getItemAt(0)
            if (item != null) {
                val sequence = item.coerceToText(appContext)
                if (sequence != null) {
                    return sequence.toString()
                }
            }
        }
    }
    return null
}


//设置适配器的列表动画
fun BaseQuickAdapter<*, *>.setAdapterAnimation(mode: Int) {
    //等于0，关闭列表动画 否则开启
    if (mode == 0) {
        this.animationEnable = false
    } else {
        this.animationEnable = true
        this.setAnimationWithDefault(BaseQuickAdapter.AnimationType.values()[mode - 1])
    }
}

fun showEditTextDialog(
    context: Context,
    title: String,
    hint: String,
    callBack: (text: String) -> Unit
) {
    val builder = QMUIDialog.EditTextDialogBuilder(context)
    builder.setTitle(title)
        .setSkinManager(QMUISkinManager.defaultInstance(context))
        .setPlaceholder(hint)
        .setInputType(InputType.TYPE_CLASS_TEXT)
        .addAction(
            "取消"
        ) { dialog, _ -> dialog.dismiss() }
        .addAction(
            "确定"
        ) { dialog, _ ->
            val text: CharSequence? = builder.editText.text
            callBack(text.toString())
            if (text.toString().isNotEmpty()) dialog.dismiss()

        }
        .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show()
}

fun showComfirmDialog(
    context: Context,
    title: String,
    hint: String,
    callBack: () -> Unit
) {
    val builder = QMUIDialog.CheckBoxMessageDialogBuilder(context)
    builder.setTitle(title)
        .setMessage(hint)
        .setChecked(true)
        .setSkinManager(QMUISkinManager.defaultInstance(context))
        .addAction(
            "取消"
        ) { dialog, _ -> dialog.dismiss() }
        .addAction(
            "确定"
        ) { dialog, _ ->
            dialog.dismiss()
            callBack()
        }
        .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show()
}

fun showSingleChoiceDialog(
    context: Context,
    items: Array<String>,
    callBack: (text: String) -> Unit
) {

    val checkedIndex = 0
    QMUIDialog.CheckableDialogBuilder(context)
        .setCheckedIndex(checkedIndex)
        .setSkinManager(QMUISkinManager.defaultInstance(context))
        .addItems(items) { dialog, which ->
//            Toast.makeText(context, "你选择了 " + items[which], Toast.LENGTH_SHORT).show()
            callBack(items[which])
            dialog.dismiss()
        }
        .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show()
}

fun showToastMsg(msg: String) {
    ToastUtils
        .make()
        .setGravity(Gravity.TOP, 0, 200)
        .setBgColor(Color.parseColor("#e10015"))
        .setTextColor(Color.parseColor("#FFFFFF")).show(msg)
}

fun toLogin(
    navController: NavController,
    callBack: () -> Unit
) {
    if (CacheUtil.isLogin()) {
        callBack
    } else {
//        navController.navigateAction(R.id.action_mainFrgment_to_loginFragment)
    }
}

fun copyContentToClipboard(context: String) {

    //获取剪贴板管理器：
    val cm: ClipboardManager =
        appContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    // 创建普通字符型ClipData
    val mClipData = ClipData.newPlainText("Label", context)
    // 将ClipData内容放到系统剪贴板里。
    cm!!.setPrimaryClip(mClipData)
    showToastMsg("内容成功复制到剪切板")
}

fun diaplayImage(imageView: ImageView, imageId: String) {

    Glide.with(appContext).asBitmap()
        .load("${SERVER_URL}/api/Upload/ViewImg?imgId=${imageId}")
        .placeholder(R.drawable.empty_image_default)
        .error(R.drawable.empty_image_default)
        .into(imageView)
}

fun showMenuDialog(
    context: Context,
    items: Array<String>,
    callBack: (item: String) -> Unit
) {
//    val items = arrayOf("选项1", "选项2", "选项3")
    QMUIDialog.MenuDialogBuilder(context)
        .setSkinManager(QMUISkinManager.defaultInstance(context))
        .addItems(items) { dialog, which ->
            callBack(items[which])
            dialog.dismiss()
        }
        .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show()
}

/**
 * 得到json文件中的内容
 * @param context
 * @param fileName
 * @return
 */
fun getJson(context: Context, fileName: String?): String {
    val stringBuilder = StringBuilder()
    //获得assets资源管理器
    val assetManager = context.assets
    //使用IO流读取json文件内容
    try {
        val bufferedReader = BufferedReader(
            InputStreamReader(
                assetManager.open(fileName!!), "utf-8"
            )
        )
        var line: String?
        while (bufferedReader.readLine().also { line = it } != null) {
            stringBuilder.append(line)
        }
        bufferedReader.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return stringBuilder.toString()
}

fun isContainChinese(str: String): Boolean {
    val p: Pattern = Pattern.compile("[\u4e00-\u9fa5]")
    val m: Matcher = p.matcher(str)
    return m.find()
}

fun callPhone(phoneNum: String, activity: Activity) {
    val intent = Intent(Intent.ACTION_DIAL)
    val data: Uri = Uri.parse("tel:$phoneNum")
    intent.data = data
    activity.startActivity(intent)
}

/**
 * 获取随机rgb颜色值
 */
fun randomColor(): Int {
    val random = Random()
    //0-190, 如果颜色值过大,就越接近白色,就看不清了,所以需要限定范围
    var red = random.nextInt(190)
    var green = random.nextInt(190)
    var blue = random.nextInt(190)

    //使用rgb混合生成一种新的颜色,Color.rgb生成的是一个int数
    return Color.rgb(red, green, blue)
}

fun getResString(id: Int): String {
    return MyApp.instance.getString(id)
}